package com.ruoyi.project.determination.algorithm;

import com.ruoyi.project.determination.pojo.AssignmentResults;
import org.apache.commons.math3.optim.MaxIter;
import org.apache.commons.math3.optim.PointValuePair;
import org.apache.commons.math3.optim.linear.*;
import org.apache.commons.math3.optim.nonlinear.scalar.GoalType;

import java.util.*;

public class GRA {

    public AssignmentResults compute(double[][] costMatrix, int[] demandVector, int[][] supplyLimitMatrix, int[] maxDemand, String product, List<String> productEnterprises) {
        int numEnterprises = costMatrix.length;  // 企业数量
        int numMonths = costMatrix[0].length;  // 月份数量

        // 目标函数的系数
        double[] objectiveCoefficients = new double[numEnterprises * numMonths];
        int idx = 0;
        for (int i = 0; i < numEnterprises; i++) {
            for (int j = 0; j < numMonths; j++) {
                objectiveCoefficients[idx++] = costMatrix[i][j];
            }
        }

        // 构建线性目标函数
        LinearObjectiveFunction objectiveFunction = new LinearObjectiveFunction(objectiveCoefficients, 0);

        // 添加约束条件
        List<LinearConstraint> constraints = new ArrayList<>();

        // 约束 (2.4): T[i,j] <= La[i,j]
        idx = 0;
        for (int i = 0; i < numEnterprises; i++) {
            for (int j = 0; j < numMonths; j++) {
                double[] constraintCoefficients = new double[numEnterprises * numMonths];
                constraintCoefficients[idx] = 1;
                constraints.add(new LinearConstraint(constraintCoefficients, Relationship.LEQ, supplyLimitMatrix[i][j]));
                idx++;
            }
        }

        // 约束 (2.5): sum(T[i,j]) >= L[j] for all j
        for (int j = 0; j < numMonths; j++) {
            double[] constraintCoefficients = new double[numEnterprises * numMonths];
            for (int i = 0; i < numEnterprises; i++) {
                constraintCoefficients[i * numMonths + j] = 1;
            }
            constraints.add(new LinearConstraint(constraintCoefficients, Relationship.GEQ, demandVector[j]));
        }

        // 约束 (2.6): sum(T[i,j]) <= U[j] for all j
        for (int j = 0; j < numMonths; j++) {
            double[] constraintCoefficients = new double[numEnterprises * numMonths];
            for (int i = 0; i < numEnterprises; i++) {
                constraintCoefficients[i * numMonths + j] = 1;
            }
            constraints.add(new LinearConstraint(constraintCoefficients, Relationship.LEQ, maxDemand[j]));
        }

        // 求解线性规划问题
        SimplexSolver solver = new SimplexSolver();
        PointValuePair solution = solver.optimize(new MaxIter(1000), objectiveFunction, new LinearConstraintSet(constraints), GoalType.MINIMIZE, new NonNegativeConstraint(true));

        // 解析结果
        double totalCost = solution.getValue();
        double[] solutionVector = solution.getPoint();

        // 将结果转换为企业分配矩阵
        double[][] allocationMatrix = new double[numEnterprises][numMonths];
        idx = 0;
        for (int i = 0; i < numEnterprises; i++) {
            for (int j = 0; j < numMonths; j++) {
                allocationMatrix[i][j] = solutionVector[idx++];
            }
        }

        // 构建 AssignmentResults 对象
        Map<String, Map<String, List<Integer>>> assignmentDetails = new HashMap<>();
        for (int i = 0; i < numEnterprises; i++) {
            String enterprise = productEnterprises.get(i);
            List<Integer> allocations = new ArrayList<>();
            for (int j = 0; j < numMonths; j++) {
                allocations.add((int) Math.round(allocationMatrix[i][j]));  // 四舍五入并转换为整数
            }
            assignmentDetails.computeIfAbsent(product, k -> new HashMap<>()).put(enterprise, allocations);
        }

        AssignmentResults result = new AssignmentResults();
        result.setScores(totalCost);
        result.setAssignmentDetails(assignmentDetails);

        return result;
    }
}